//
// Process.h
// Usage: Process object
// CreateDate: 2009-04-05
// Author: MaJiuyue
//
#ifndef _PROCESS_H_ 
#define _PROCESS_H_

#include <UString.h>
#include <LinkedList.h>
#include "Context.h"
#include "Thread.h"
#include "ScheduleObject.h"
#include "../ipc/MessageBox.h"
#include "../fs/FileControlBlock.h"

#define PID_ANY		(pid_t)0xFFFF

/* Process */
class Process:public ScheduleObject
{
private:
	/* Process property */
	pid_t m_PID;			// Process PID
	int m_Priority;			// Process priority

	/* Process status */
	enum PROCESS_STATUS m_ProcessStatus;
	Context	m_Context;		// Process context
		// I/O permit bitmap

	/* IPC mbox */
	MessageBox mbox;
	
	/* FCB */
	FileControlBlock FCB;

	/* Thread info */
	LinkedList<Thread *> m_Threads;
	LinkedList<Process *> m_Childs;
	Process *m_Parent;

	pid_t m_WaitPID;

public:
	Process(pid_t pid, int priority, int umbox_size=64);
	~Process();
protected:
	Process(Process& target, pid_t child_pid);

public:
	/* Switch to self's context */
	void SwitchContext();

	/* Call call gate */
	u32 CallGate();

	/* Create child process */
	Process * CreateChildProcess(pid_t child_pid); 

	/* Get process's context */
	Context * GetContext() { return &m_Context; }

	/* Get process's mbox */
	MessageBox * GetMBox() { return &mbox; }
	
	/* Get FCB */
	FileControlBlock * GetFCB() { return &FCB; }

	/* Get thread by # */
	Thread * GetThread() { return m_Threads.getFirst(); }

	/* Get process's PID */
	pid_t GetPID() { return m_PID; }

	/* Process priority */
	int GetPriority() { return m_Priority; }
	void SetPriority(int priority) { m_Priority = priority; }
	
	/* Process status */
	PROCESS_STATUS GetProcessStatus() { return m_ProcessStatus; }
	void SetProcessStatus(PROCESS_STATUS ps) { m_ProcessStatus = ps; }

	//
	int Exit();

	//panduan shifou wei child process,shi panduan child process state,PS_DEAD,quchu ebx -> eax,fou zuse himself	
	int WaitPID(pid_t pid);
	pid_t GetWaitPID(){return m_WaitPID;}
	Process *GetParent(){return m_Parent;}

public:
	virtual int GetInitialTick()	{ return m_Priority+4; }
	virtual void Restart()	{ GetThread()->Restart(); }
	virtual void ResetTick(int priority) { }
};

Process * GetCurrentProcess();

#endif

